﻿namespace Dapper.Tests
{
    using System.Data.SqlClient;
    using System.Linq;

    using Xunit;

    public class Tests
    {
        [Fact]
        public void TestBasicStringUsageAsync()
        {
            using (var connection = this.GetOpenConnection())
            {
                var query = connection.QueryAsync<string>("select 'abc' as [Value] union all select @txt", new { txt = "def" });
                var arr = query.Result.ToArray();
                Assert.Equal(new[] { "abc", "def" }, arr);
            }
        }

        [Fact]
        public void TestClassWithStringUsageAsync()
        {
            using (var connection = this.GetOpenConnection())
            {
                var query = connection.QueryAsync<BasicType>("select 'abc' as [Value] union all select @txt", new { txt = "def" });
                var arr = query.Result.ToArray();
                Assert.Equal(new[] { "abc", "def" }, arr.Select(x => x.Value));
            }
        }

        [Fact]
        public void TestMultiMapWithSplitAsync()
        {
            var sql = @"select 1 as id, 'abc' as name, 2 as id, 'def' as name";
            using (var connection = this.GetOpenConnection())
            {
                var productQuery = connection.QueryAsync<Product, Category, Product>(sql, (prod, cat) =>
                {
                    prod.Category = cat;
                    return prod;
                });

                var product = productQuery.Result.First();
                // assertions
                Assert.Equal(1, product.Id);
                Assert.Equal("abc", product.Name);
                Assert.Equal(2, product.Category.Id);
                Assert.Equal("def", product.Category.Name);
            }
        }

        [Fact]
        public void TestWithExecuteAsync()
        {
            using (var testConnection = this.GetOpenConnection())
            {
                using (var connection = this.GetOpenConnection())
                {
                    var createTable = @"IF (NOT EXISTS (SELECT * 
                 FROM INFORMATION_SCHEMA.TABLES 
                 WHERE TABLE_SCHEMA = 'dbo' 
                 AND  TABLE_NAME = 'MeterData'))
                BEGIN
                    CREATE TABLE [dbo].[MeterData](
	                [TenantId] [nvarchar](32) NOT NULL,
	                [Value] [float] NOT NULL)
                END";

                    var cmd = new SqlCommand(createTable, testConnection);
                    cmd.ExecuteNonQuery();

                    cmd = new SqlCommand("delete from dbo.[MeterData]", testConnection);
                    cmd.ExecuteNonQuery();

                    var query = @"INSERT INTO dbo.[MeterData] ([TenantId], [Value])  VALUES ('T1', 1)";

                    var result = connection.ExecuteAsync(query).Result;

                    cmd = new SqlCommand("SELECT * FROM dbo.[MeterData]", testConnection);
                    var reader = cmd.ExecuteReader();
                    var count = 0;
                    while (reader.Read())
                    {
                        count++;
                    }

                    Assert.Equal(1, count);
                }
            }
        }

        class Product
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public Category Category { get; set; }
        }
        class Category
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Description { get; set; }
        }

        class BasicType
        {
            public string Value { get; set; }
        }

        public static readonly string connectionString = "Data Source=.;Initial Catalog=tempdb;Integrated Security=True";

        public SqlConnection GetOpenConnection()
        {
            var connection = new SqlConnection(connectionString);
            connection.Open();
            return connection;
        }
    }
}